package club.babyf.nativeai.utils;

import club.babyf.nativeai.common.exception.BusinessException;
import club.babyf.nativeai.common.exception.ErrorCode;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.io.RandomAccessReadBuffer;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.stream.Collectors;

/**
 * FileParser.
 *
 * @author zhanglei.
 * @date 2025/3/17 11:39.
 * @description 文件解析工具.
 */
public class FileParser {

    public static String parseFile(MultipartFile file) throws IOException {
        String contentType = file.getContentType();
        if (contentType == null) throw new IllegalArgumentException("未知文件类型");
        return switch (contentType) {
            case "application/pdf" -> parsePdf(file.getInputStream());
            case "text/plain" -> parseText(file.getInputStream());
            case "application/vnd.openxmlformats-officedocument.wordprocessingml.document" ->
                    parseDocx(file.getInputStream());
            default ->
                    throw new BusinessException("不支持的文件类型: " + contentType, ErrorCode.PARAMS_ERROR.getCode());
        };
    }

    /**
     * PDF解析实现
     *
     * @param is 文件输入流
     * @return 解析后的文本内容
     * @throws IOException 文件读取异常
     */
    private static String parsePdf(InputStream is) throws IOException {
        try (PDDocument document = Loader.loadPDF(new RandomAccessReadBuffer(is))) {
            PDFTextStripper stripper = new PDFTextStripper();
            return stripper.getText(document);
        }
    }

    /**
     * 纯文本解析
     *
     * @param is 文件输入流
     * @return 解析后的文本内容
     * @throws IOException 文件读取异常
     */
    private static String parseText(InputStream is) throws IOException {
        return new String(is.readAllBytes(), StandardCharsets.UTF_8);
    }

    /**
     * DOCX解析实现
     *
     * @param is 文件输入流
     * @return 解析后的文本内容
     * @throws IOException 文件读取异常
     */
    private static String parseDocx(InputStream is) throws IOException {
        XWPFDocument doc = new XWPFDocument(is);
        return doc.getParagraphs().stream()
                .map(XWPFParagraph::getText)
                .filter(text -> !text.trim().isEmpty())
                .collect(Collectors.joining("\n"));
    }

}
